package cate.game.play.proce.turn;

import cate.common.table.d.GDFight;
import cate.game.play.fighter.Fighter;
import cate.game.play.proce.action.ctx.TimeActionCtx;
import cate.game.play.proce.move.AppendMove;
import cate.game.play.proce.move.MoveCtx;
import cate.game.play.proce.round.RoundCtx;
import cate.game.play.proce.stat.TurnStat;
import cate.game.play.skill.Skill;
import easy.java.dev.note.NoteClass;
import easy.java.dev.note.NoteField;

import java.util.Comparator;
import java.util.LinkedList;

@NoteClass("单个英雄的轮次ctx")
public class TurnCtx {

	@NoteField("回合ctx")
	private RoundCtx round;

	@NoteField("turn统计")
	private TurnStat stat;

	@NoteField("当前轮次行动发起者")
	private Fighter actor;

	@NoteField(value = "本轮次行动者放的技能",detail = "如果为null则需要根据cd选择")
	private Skill skill;

	@NoteField(value = "追加行动",detail = "单个轮次中追加的出手 无法再衍生新的出手")
	private LinkedList<AppendMove> appendMoves = new LinkedList<>();

	@NoteField(value = "当前是队伍里第几个行动的",detail = "不包括追加行动")
	private int teamOrder;

	@NoteField(value = "是否是追加的turn",detail = "追加的turn不能触发物连法连")
	private boolean append;

	public TurnCtx(RoundCtx round, Fighter actor, Skill skill, boolean append) {
		this.round = round;
		this.actor = actor;
		this.skill = skill;
		this.append = append;
		this.stat = new TurnStat(round.stat);
	}

	public void start() {
		MoveCtx ctx = new MoveCtx(this, actor, skill, append);
		if (actor.getType() == GDFight.Fighter.HERO && !append) {
			teamOrder = round.stat.getCurTeamOrder(actor.getTeam());
		}
		ctx.start();
		if (actor.getType() == GDFight.Fighter.HERO && !append && ctx.stat.move) {
			round.stat.recordPid(actor.getTeam(), actor.getPid());
		}
		handleAppendMove();
	}

	public RoundCtx getRound() {
		return round;
	}

	public int getTeamOrder() {
		return teamOrder;
	}

	public TurnStat getStat() {
		return stat;
	}

	/**
	 * 记录需要追加的行动
	 * @param newMove
	 */
	public void addAppend(AppendMove newMove) {
		appendMoves.add(newMove);
	}

	/**
	 * 死亡时移除之前记录追加的行动
	 * @param fighter
	 */
	public void removeAppend(Fighter fighter) {
		appendMoves.removeIf(m -> m.actor.getPid() == fighter.getPid());
	}

	/** 执行追加行动逻辑 */
	private void handleAppendMove() {
		while (!appendMoves.isEmpty()) {
			if (this.round.getTeamVs().isOver()) {
				break;
			}
			appendMoves.sort(Comparator.comparing((AppendMove move) -> -move.actor.attr.total().speedTotal()));
			AppendMove appendMove = appendMoves.removeFirst();
			if (!appendMove.inValid(this)) {
				appendMove.beforeAppendMove(this);
				MoveCtx ctx = new MoveCtx(this, appendMove.actor, appendMove.skill,true);
				ctx.param.setHpChangeRate(appendMove.hpChangeRate);
				ctx.start();
				appendMove.afterAppendMove(this);
			} else {
				appendMove.onAppendMoveFail(this);
			}
		}
	}

	/**
	 * 构建时间action
	 * @return
	 */
	public TimeActionCtx buildTimeAction(){
		return getRound().buildTimeAction();
	}
}
